package com.android.driveuploader;

/**
 * Created by srikanthg on 8/27/14.
 */

        import android.app.WallpaperManager;
        import android.util.Log;

        import java.io.BufferedReader;
        import java.io.DataOutputStream;
        import java.io.FileInputStream;
        import java.io.IOException;
        import java.io.InputStream;
        import java.io.InputStreamReader;
        import java.net.HttpURLConnection;
        import java.net.URL;

/**
 * This class is a simple implementation of the protocol to upload a file to drive in order to
 * demonstrate how to use an OAuth 2.0 token. Alternatively, the Google Play Services API should be
 * used.
 */
public class DriveUploader {

    /**
     * Constant for the OAuth 2.0 scope for Google Drive uploads
     */
    public static final String AUTHTOKENSCOPE_DRIVE = "https://www.googleapis.com/auth/drive";

    private static final String TAG = "DriveUploader";

    // Constants for uploading to drive.
    private static final String DRIVE_UPLOAD_URL =
            "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart";

    // Constants for uploading to drive.
    private static final String DRIVE_GET_URL =
            "https://www.googleapis.com/drive/v2/";

    // Constants for creating multi-part upload data.
    private static final String CR_NL = "\r\n";
    private static final String DASHDASH = "--";
    private static final String BOUNDARY =
            "*****" + Long.toString(System.currentTimeMillis()) + "*****";

    private final String token;

    /**
     * Constructor that sets the OAuth 2.0 token and the DriveUploadListener.
     */
    public DriveUploader(String token) {
        this.token = token;
    }

    /**
     * Function that does the upload synchronously.
     *
     * This function should be called on a background thread only.
     *
     * @return wether the upload was succesful.
     */
    public boolean uploadToDrive(String filename, String contentType, InputStream fileContent)
            throws IOException {
        // Implementing the drive upload protocol following
        // https://developers.google.com/drive/web/manage-uploads#multipart
        HttpURLConnection connection = createConnection(token, BOUNDARY);
        DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());

        // Write the JSON metadata.
        outputStream.writeBytes(DASHDASH + BOUNDARY + CR_NL);
        writeMetaData(outputStream, filename);

        // Write the part separator.
        outputStream.writeBytes(DASHDASH + BOUNDARY + CR_NL);

        // Write the JPEG image.
        writeJPEGImageData(fileContent, contentType, outputStream);

        // Finalize the message.
        outputStream.writeBytes(DASHDASH + BOUNDARY + DASHDASH);
        outputStream.flush();
        outputStream.close();

        // Read the response from the server.
        String response = inputStreamToString(connection.getInputStream());
        Log.i(TAG, "Result: " + response);

        return connection.getResponseCode() == 200;
    }

    /**
     * Function that does the upload synchronously. TODO:
     *
     * This function should be called on a background thread only.
     *
     * @return wether the upload was succesful.
     */
    public InputStream getFolders(String folderID)
            throws IOException {
        // Implementing the drive upload protocol following
        // https://developers.google.com/drive/web/manage-uploads#multipart
        //GET Request: https://www.googleapis.com/drive/v2/files/folderId/children
//        HttpURLConnection connection = createGetConnection(token);
//        connection.connect();

        //Download file URL:
        String downloadUrl = "https://doc-0c-9c-docs.googleusercontent.com/docs/securesc/gp195vgpeg30coqg68pt1r09o13gf33p/8laflksrl6m23rle778cq44uj57nuobe/1409356800000/07236073452741033222/07236073452741033222/12i2EQ4qLGb1K650BAu4WEXSZe5jNitz5Iw?h=16653014193614665626&e=download&gd=true";
        URL url = new URL(downloadUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        //connection.setDoInput(true);
        //connection.setDoOutput(true);
        connection.setUseCaches(false);
        //connection.setRequestProperty("Content-Type", "multipart/related; boundary=" + boundary);
        connection.setRequestProperty("Authorization", "Bearer " + token);
        InputStream inputStream = connection.getInputStream();
        return inputStream;



        //DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());

        // Write the JSON metadata.
        //outputStream.writeBytes(DASHDASH + BOUNDARY + CR_NL);
        //writeMetaData(outputStream, filename);

        // Write the part separator.
        //outputStream.writeBytes(DASHDASH + BOUNDARY + CR_NL);

        // Write the JPEG image.
        //writeJPEGImageData(fileContent, contentType, outputStream);

        // Finalize the message.
        //outputStream.writeBytes(DASHDASH + BOUNDARY + DASHDASH);
        //outputStream.flush();
        //outputStream.close();

        // Read the response from the server.
        //String response = inputStreamToString(connection.getInputStream());
        //Log.i(TAG, "Result:************** " + response);

        //return connection.getResponseCode() == 200;
    }
    // Helper method that creates an OAuth 2.0 authenticated HTTP POST connection.
    private HttpURLConnection createConnection(String token, String boundary) throws IOException {
        // Setup an HTTP POST connection.
        URL url = new URL(DRIVE_UPLOAD_URL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestProperty("Content-Type", "multipart/related; boundary=" + boundary);
        connection.setRequestProperty("Authorization", "Bearer " + token);
        return connection;
    }

    // Helper method that creates an OAuth 2.0 authenticated HTTP POST connection.
    private HttpURLConnection createGetConnection(String token) throws IOException {
        // Setup an HTTP POST connection.
        URL url = new URL(DRIVE_GET_URL + "files/root/children");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        //connection.setDoInput(true);
        //connection.setDoOutput(true);
        connection.setUseCaches(false);
        //connection.setRequestProperty("Content-Type", "multipart/related; boundary=" + boundary);
        connection.setRequestProperty("Authorization", "Bearer " + token);
        return connection;
    }
    // Helper method that writes the JSON metadata as defined in the Google Drive JSON API.
    private void writeMetaData(DataOutputStream outputStream, String filename) throws IOException {
        outputStream.writeBytes("Content-Type: application/json; charset=UTF-8" + CR_NL + CR_NL);
        outputStream
                .writeBytes("{" + CR_NL + "\"title\": \"" + filename + "\"" + CR_NL + "}" + CR_NL + CR_NL);
    }

    // Helper method that writes a JPEG image.
    private void writeJPEGImageData(InputStream fileContent, String contentType,
                                    DataOutputStream outputStream) throws IOException {
        outputStream.writeBytes("Content-Type: " + contentType + CR_NL);
        outputStream.writeBytes("Content-Transfer-Encoding: binary" + CR_NL);
        outputStream.writeBytes(CR_NL);

        copyFromInputStreamToOutputStream(fileContent, outputStream);
        outputStream.writeBytes(CR_NL + CR_NL);
    }

    // Helper method to read a stream into a string.
    private String inputStreamToString(InputStream inputStream) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String read = bufferedReader.readLine();
        while (read != null) {
            stringBuilder.append(read);
            read = bufferedReader.readLine();
        }
        return stringBuilder.toString();
    }

    // Helper function to copy from one stream to another.
    private void copyFromInputStreamToOutputStream(InputStream inputStream,
                                                   DataOutputStream outputStream)
            throws IOException {
        int maxBufferSize = 1024 * 1024;

        int bytesAvailable = inputStream.available();
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
        byte[] buffer = new byte[bufferSize];

        int bytesRead = inputStream.read(buffer, 0, bufferSize);
        while (bytesRead > 0) {
            outputStream.write(buffer, 0, bufferSize);
            bytesAvailable = inputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = inputStream.read(buffer, 0, bufferSize);
        }
        inputStream.close();
        outputStream.flush();
    }
}
